「Vue自我检验」Vue 组件化编程,你了解多少?

您所在的位置:网站首页 vue v-on指令 「Vue自我检验」Vue 组件化编程,你了解多少?

「Vue自我检验」Vue 组件化编程,你了解多少?

#「Vue自我检验」Vue 组件化编程,你了解多少?| 来源: 网络整理| 查看: 265

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。

Vue 组件化编程 非单文件组件

非单文件组件即所有组件写在同一个文件里。

基本使用

定义组件:

使用 Vue.extend(options) 创建,和 new Vue(options) 的区别; el 不写,最终所有的组件都要经过 vm 的管理,由 vm 的 el 决定服务哪个容器 data 必须写成函数,避免组件被复用时,数据存在引用关系 使用 template 节点可配置组件结构

注册组件;

局部注册:components 选项 全局注册:Vue.component('组件名',组件)

使用组件:

复制代码 // 创建 student 组件 const student = Vue.extend({ template: ` 学生姓名:{{studentName}} `, data() { return { studentName: '张三', } }, }) // 创建 hello 组件 const hello = Vue.extend({ template: ` {{name}} `, data() { return { name: 'Tom', } }, }) // 创建 school 组件 const school = Vue.extend({ name: 'school', template: ` 学校名称:{{name}} `, data() { return { name: '北京大学', } }, // 组件嵌套 components: { student, }, }) // 全局注册 Vue.component('hello', hello) // 不用使用el new Vue({ el: '#root', // 局部注册 components: { school, }, }) 复制代码

注意事项:

组件名 一个单词:school, School 多个单词:my-school, MySchool(需要 vue-cli 支持) 使用组件 (需要 vue-cli 支持) const school = Vue.extend(options) 可简写为 const school = options 关于 VueComponent 构造函数 组件本质是一个名为 VueComponent 的构造函数,不是程序员定义的,是 Vue.extend 生成的 const school = Vue.extend({...}) console.dir(school) //ƒ VueComponent (options) 复制代码

使用组件时,Vue 自动创建组件实例对象,即 new VueComponent(options) 是 Vue 做的

每次调用 Vue.extend,返回的都是一个全新的 VueComponent 构造函数

组件的 this 指向 VueComponent 实例对象,而非 Vue 实例对象

重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype ,这个改动使得组件实例对象得以访问 Vue 原型上的属性方法

image-20220310201151625

单文件组件

单文件组件即 .vue 文件

scoped 解决样式冲突 原理:为当前组件所有 DOM 元素分配唯一的自定义属性,写样式时使用属性选择器防止样式冲突问题 scoped 只给子组件最外层的 div 添加了自定义属性 [data-v-xxx] ,子组件内部的标签并没有添加。因此父组件只能修改子组件最外层的 div 样式,修改子组件内层元素的样式是不可行的 若想让某些样式对子组件生效,需使用 /deep/ 深度选择器 或者 sass 的 ::v-deep stylus使用>>> /* 细细品味 */ .title { /* 不加 /deep/,选择器格式为 .title[data-v-052242de] */ color: blue; } /deep/ .title { /* 加 /deep/,选择器格式为 [data-v-052242de] .title */ color: blue; } 复制代码 组件通信 1. 自定义属性 props

父传子、子传父

props 验证:

基础类型检查:String, Number, Boolean, Array, Object, Date, Function, Symbol 多个可能的类型 必填项检查 默认值(opens new window) 自定义验证函数 validator props 是只读的,若是对象,对象内部的修改不报错,但不推荐

父传子:

复制代码 父组件传过来的值:{{ num }} 父组件传过来的值:{{ msg }} 复制代码

子传父:

父组件通过 props 给子组件传递函数,子组件调用该函数即可修改父组件的数据 组件 methods 里函数的 this 始终指向该组件实例,可理解为 Vue 底层对这些函数做了bind处理 通过bind修改 this 指向后的新函数,其 this 指向不能再次修改 思否文章(opens new window) 不推荐该方式进行子传父,推荐使用自定义事件 复制代码 export default { data() { return { count: 1, } }, methods: { addCount() { this.count++ }, }, } 复制代码 export default { props: ['addCount'], methods: { add() { this.addCount() }, }, } 复制代码 2. 自定义事件

子传父

子组件触发自定义事件,并传递数据:

解绑自定义事件this.$off('count-change') // 子组件 data() { return { count: 1 } }, methods: { add() { this.count += 1 this.$emit('count-change', this.count) } } 复制代码

父组件监听子组件的自定义事件,并调用回调函数处理数据:

父组件通过 this.$refs.xxx.$on('事件名称',回调) 监听子组件自定义事件时,回调函数要么配置在 methods 中,要么用箭头函数,否则 this 指向会出问题 组件上也可以绑定原生 DOM 事件,需要使用 native 修饰符 若想让自定义事件只触发一次,可以使用 once 修饰符,或 $once 方法 复制代码 export default { data() { return { father: 1, } }, methods: { getNewCount(val) { // 看传了多少个参数,对应接受多少个参数 this.father = val }, }, mounted() { // 方式二 this.$refs.sonRef.$on('count-change', this.getNewCount) // 或 this.$refs.sonRef.$on('count-change', (val) => (this.father = val)) }, } 复制代码 3. EventBus 全局事件总线

思想:弄一个所有组件实例都能访问到的 Vue 实例对象,Vue 原型上包含事件处理的相关方法,包括 $on, $emit, $off, $once

方式一

安装全局事件总线:

// main.js new Vue({ ... beforeCreate() { Vue.prototype.$bus = this } ... }) 复制代码

数据接收方为自定义事件绑定回调函数:

export default { methods: { handleData() {...} }, created() { this.$bus.$on('share', this.handleData) }, beforeDestroy() { // 组件销毁,解绑事件 this.$bus.$off('share') } } 复制代码

数据发送方触发自定义事件:

export default { methods: { sendData() { this.$bus.$emit('share', 666) }, }, } 复制代码

方式二

创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象。

// eventBus.js import Vue from 'vue' export default new Vue() 复制代码

在数据发送方,调用 bus.$emit('事件名称', 要发送的数据) 方法触发自定义事件。

// 数据发送方 import bus from './eventBus.js' export default { data() { return { message: 'hello', } }, methods: { sendData() { bus.$emit('share', this.message) }, }, } 复制代码

在数据接收方,通过 bus.$on('事件名称', 事件处理函数) 为自定义事件注册事件处理函数。

// 数据接收方 import bus from './eventBus.js' export default { data() { return { msg: '', } }, // 细节1:在 created 钩子中注册函数 created() { // 细节2:使用箭头函数,则 this 指向该组件而非 bus bus.$on('share', (val) => { this.msg = val }) }, } 复制代码 4. 消息订阅与发布

与全局事件总线很相似,因此一般用事件总线,不用这个

安装第三方库 PubSubJS :npm install -S pubsub.js

订阅消息:

import pubsub from 'pubsub-js' export default { methods: { handleData(messageName, data) {...} }, created() { this.pubId = pubsub.subscribe('share', this.handleData) // or this.pubId = pubsub.subscribe('share', (messageName, data) => { console.log(data) }) }, beforeDestroy() { // 组件销毁,取消订阅 pubsub.unsubscribe(this.pubId) } } 复制代码

发布消息:

import pubsub from 'pubsub-js' export default { methods: { sendData() { pubsub.publish('share', 666) }, }, } 复制代码 5. ref / $refs

ref 用于给 DOM 元素或子组件注册引用信息。每个 vue 实例都有 $refs 对象,里面存储着 DOM 元素或子组件的引用。通过该方式可以获取到 DOM 元素或子组件实例。

ref / $refs 的方式只能实现父传子,是单向传递数据。

这是段落 获取 DOM 元素 获取子组件实例引用 复制代码 methods: { getRef() { // 获取元素的引用 console.log(this.$refs.pp) this.$refs.pp.style.color = 'red' }, getComponent() { console.log(this.$refs.sonRef) // 可以访问子组件的数据和方法 this.$refs.sonRef.count = 1 this.$refs.sonRef.add() } } 复制代码 6. this.$parent

子组件可以访问父组件

// 父组件的方法 methods:{ showfa(){ console.log("我是父组件的方法"); } }, // 子组件通过 this.$parent.showfa() // 可以访问父组件的方法 复制代码 7. this.$root

子组件可以访问根组件的方法

// 根组件的方法 methods: { showroot(){ console.log('我是根组件的方法'); } }, // 子组件 this.$root.showroot() //访问根组件的方法 复制代码 8. provide 与 inject

只支持Vue 3.x后使用

img

作用:实现祖与后代组件间通信

套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据

具体写法:

祖组件中:

setup(){ ...... let car = reactive({name:'奔驰',price:'40万'}) provide('car',car) ...... } 复制代码

后代组件中:

setup(props,context){ ...... const car = inject('car') return {car} ...... } 复制代码 $nextTick(cb)

组件的 $nextTick(cb) 方法,会把 cb 回调推迟到下一个 DOM 更新周期之后执行,即在 DOM 更新完成后再执行回调,从而保证 cb 回调可以获取最新的 DOM 元素。

methods: { showInput() { this.inputVisible = true // 对输入框的操作推迟到 DOM 更新完成之后 this.$nextTick(() => { this.$refs.input.focus() }) } } 复制代码


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3